home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993 April: Penguin on DISC / ADC Developer CD (1993-04) (''Penguin On DISC'')_iso / Dev.CD Apr 93.iso / System Software / System Extensions / AppleScript Beta / Development Tools / Sample Applications / 7Edit 3.0d7 / 7Edit Source / 7Edit C 3.0d7 / SVEditFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-24  |  14.8 KB  |  667 lines  |  [TEXT/MPS ]

  1. /*
  2.     SVEditFile.c
  3.     
  4.     Version 3.0d7
  5.     
  6.     Copyright © Apple Computer UK Ltd. 1991,1992
  7.     
  8.     All rights reserved.
  9.     
  10.     Produced by : UK Developer Technical Support
  11.     AppleLink   : UK.DTS
  12. */
  13.  
  14. /*
  15.   Changes for 3.0d4:
  16.         3-Jul-92 : NH : Change kAEAskUser to kAEAskU on call to DoClose
  17.         
  18. */
  19.     
  20. #include <Errors.h>
  21. #include <Resources.h>
  22. #include <Desk.h>
  23. #include <PLStringFuncs.h>
  24. #include <AppleEvents.h>
  25. #include <AERegistry.h>
  26. #include "SVEditFile.h"
  27.  
  28. /**-----------------------------------------------------------------------
  29.         Name:             FileError
  30.         Purpose:        Puts up an error alert.
  31.     -----------------------------------------------------------------------**/
  32.  
  33.     
  34. #pragma segment File
  35.  
  36. pascal void FileError(Str255 s, Str255 f)
  37.   {
  38.     short    alertResult;
  39.  
  40.     SetCursor(&qd.arrow);
  41.         ParamText(s, f, "", "");
  42.     alertResult = Alert(ErrorAlert, nil);
  43.     }
  44.  
  45. /**-----------------------------------------------------------------------
  46.         Name:             DoClose
  47.         Purpose:        Closes a window.
  48.     -----------------------------------------------------------------------**/
  49.  
  50. #pragma segment File
  51.  
  52. pascal OSErr DoClose(WindowPtr aWindow,Boolean canInteract,DescType dialogAnswer)
  53.   {
  54.     DPtr    aDocument;
  55.     short   alertResult;
  56.     Str255  theName;
  57.         OSErr   myErr;
  58.                         
  59.         myErr = noErr;
  60.         
  61.     if (gWCount>0)
  62.       {
  63.         aDocument = DPtrFromWindowPtr(aWindow);
  64.             
  65.                 if (aDocument->dirty)
  66.                     if (canInteract && (dialogAnswer==kAEAsk))
  67.                         {
  68.                             if (aDocument->everSaved == false)
  69.                                 GetWTitle(aWindow, theName); /* Pick it up as a script may have changed it */
  70.                             else
  71.                                 PLstrcpy(theName, aDocument->theFileName);
  72.                                 
  73.                             ParamText("\pSave Changes for ", theName, "", "");
  74.                           SetCursor(&qd.arrow);
  75.                             alertResult = Alert(AdviseAlert, nil);
  76.                             switch (alertResult) {
  77.                               case aaSave    :if (aDocument->everSaved == false)
  78.                                                                     {
  79.                                                                         myErr = GetFileNameToSaveAs(aDocument);
  80.                                                                         if (myErr == noErr)
  81.                                                                             myErr = DoSave(aDocument, aDocument->theFSSpec);
  82.                                                                             
  83.                                                                         if (myErr==noErr)
  84.                                                                             AssocAllSections(aDocument);
  85.                                                                     }
  86.                                                                 else
  87.                                                                     myErr = SaveUsingTemp(aDocument);
  88.                                                                 break;
  89.                                                                 
  90.                                 case aaCancel : return(userCanceledErr);
  91.                                                 break;
  92.                                                                 
  93.                                 case aaDiscard: aDocument->dirty = false;
  94.                             }
  95.                         }
  96.                     else
  97.                         {
  98.                             if (dialogAnswer==kAEYes)
  99.                                 if (aDocument->everSaved == false)
  100.                                     {
  101.                                         if (canInteract)
  102.                                             {
  103.                                               myErr = GetFileNameToSaveAs(aDocument);
  104.                                                 if (myErr==noErr)
  105.                                                     myErr = DoSave(aDocument, aDocument->theFSSpec);
  106.                                                 if (myErr==noErr)
  107.                                                     AssocAllSections(aDocument);
  108.                                             }
  109.                                         else    
  110.                                             return(errAENoUserInteraction);
  111.                                     }
  112.                                 else
  113.                                     myErr = SaveUsingTemp(aDocument);
  114.                             else
  115.                                 myErr = noErr; /* Don't save */
  116.                         }
  117.                 
  118.                 if (myErr==noErr)
  119.                     {
  120.                         if (aDocument->numSections)
  121.                             DeRegisterAllSections(aDocument);
  122.                         CloseMyWindow(aWindow);
  123.                     }
  124.             }
  125.         else
  126.           myErr = errAEIllegalIndex;
  127.             
  128.         return(myErr);
  129.     }
  130.  
  131. #pragma segment File
  132.  
  133. //  DoQuit
  134. //  saveOpt - one of kAEAsk,kAEYes,kAENo
  135. //  if kAEYes or kAEAsk then AEInteactWithUser should have been called
  136. //  before DoQuit. Assumes that it can interact if it needs to.
  137.  
  138. pascal void DoQuit(DescType saveOpt)
  139.   {
  140.     WindowPtr    aWindow;
  141.     WindowPtr    nextWindow;
  142.     WindowPeek   nextWPeek;
  143.     short        theKind;
  144.     OSErr        check;
  145.  
  146.     aWindow = FrontWindow();
  147.      
  148.         while (aWindow)
  149.             {
  150.                 nextWPeek  = ((WindowPeek)aWindow)->nextWindow;
  151.                 nextWindow = &nextWPeek->port;
  152.                 if (Ours(aWindow))
  153.                     {
  154.                         check = DoClose(aWindow, true, saveOpt);
  155.                         if (check!=noErr)
  156.                             return;
  157.                     }
  158.                 else
  159.                     {
  160.                         theKind = ((WindowPeek)aWindow)->windowKind;
  161.                         if (theKind < 0)
  162.                             CloseDeskAcc(theKind);
  163.                     }
  164.                 aWindow = nextWindow;
  165.             }     /*WHILE loop*/
  166.         gQuitting = true;
  167.     }
  168.  
  169. pascal OSErr GetFile(FSSpec *theFSSpec)
  170.   {
  171.     SFTypeList         myTypes;
  172.     StandardFileReply  reply;
  173.  
  174.         myTypes[0] = 'TEXT';
  175.  
  176.         StandardGetFile(nil, 1, myTypes, &reply);
  177.  
  178.         if (reply.sfGood)
  179.             {
  180.                 *theFSSpec = reply.sfFile;
  181.                 return(noErr);
  182.             }
  183.         else
  184.             return(userCanceledErr);
  185.  }
  186.  
  187. #pragma segment File
  188.  
  189.  
  190. pascal OSErr DoCreate(FSSpec theSpec)
  191.   {
  192.       OSErr err;
  193.  
  194.       err = FSpCreate(&theSpec, SVEditAppSig, 'TEXT', smSystemScript);
  195.  
  196.       if (err != noErr)
  197.               ShowError("\pDoCreate", err);
  198.                 
  199.             return(err);
  200.     }
  201.  
  202. #pragma segment File
  203.  
  204.  
  205. pascal OSErr WriteFile(DPtr      theDocument,
  206.                                              short     refNum,
  207.                        FSSpec    theFSSpec)
  208.   {
  209.     short        resFile;
  210.     long         length;
  211.     HHandle      theHHandle;
  212.     StScrpHandle theSHandle;
  213.     OSErr        err;
  214.     StringHandle theAppName;
  215.         short        oldSelStart;
  216.         short        oldSelEnd;
  217.         Handle       thePHandle;
  218.         Handle       myText;
  219.                 
  220. /*        WriteFile := 1; */
  221.  
  222.     /*first write out the text to the data fork*/
  223.         
  224.         length = (*(theDocument->theText))->teLength;
  225.         
  226.         myText = (*(theDocument->theText))->hText;
  227.         
  228.     HLock(myText);
  229.     
  230.         err = FSWrite(refNum, &length, *myText);
  231.         if (err)
  232.           return(err);
  233.             
  234.     HUnlock(myText);
  235.  
  236.         /*we are writing to a temporary file, so we need to create the resource file*/
  237.         /*before writing out the resources*/
  238.         /*now open the resource file*/
  239.         
  240.         HCreateResFile(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name);
  241.         err = ResError();
  242.         if (err)
  243.           {
  244.                 ShowError("\pHCreateResFile", err);
  245.                 return(err);
  246.             }
  247.  
  248.     resFile = HOpenResFile(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name, fsWrPerm);
  249.     err = ResError();
  250.  
  251.     if (err)
  252.           {
  253.                 ShowError("\pHOpenResFile", err);
  254.                 return(err);
  255.             }
  256.  
  257.      /*write out our 'TFSF' resource to file*/
  258.                 
  259.         oldSelStart = (*(theDocument->theText))->selStart;
  260.         oldSelEnd   = (*(theDocument->theText))->selEnd;
  261.         TESetSelect(0,32000, theDocument->theText);
  262.                 
  263.     theSHandle = GetStylScrap(theDocument->theText);
  264.                 
  265.         TESetSelect(oldSelStart,oldSelEnd, theDocument->theText);
  266.                 
  267.     AddResource((Handle)theSHandle, 'TFSF', 255, "\pStyle Info");
  268.     err = ResError();
  269.     if (err)
  270.           {
  271.                 ShowError("\pAddResource- TFSF", err);
  272.                 return(err);
  273.             }
  274.                     
  275.         /* write out the printer info */
  276.                 
  277.         if (theDocument->thePrintSetup)
  278.             {
  279.                 thePHandle = (Handle)theDocument->thePrintSetup;
  280.                 err = HandToHand(&thePHandle);
  281.                 
  282.                 AddResource(thePHandle, 'TFSP', 255, "\pPrinter Info");
  283.                 err = ResError();
  284.                 if (err)
  285.                     {
  286.                         ShowError("\pAddResource- TFSP", err);
  287.                         return(err);
  288.                     }
  289.             }
  290.                 
  291.                 
  292.         theHHandle = (HHandle)NewHandle(sizeof(HeaderRec));
  293.     HLock((Handle)theHHandle);
  294.  
  295.         GetFontName(theDocument->theFont, &(*theHHandle)->theFont);
  296.         (*theHHandle)->theSize     = theDocument->theSize;
  297.         (*theHHandle)->theStyle    = theDocument->theStyle;
  298.         (*theHHandle)->lastID      = theDocument->lastID;
  299.         (*theHHandle)->numSections = theDocument->numSections;
  300.  
  301.         HUnlock((Handle)theHHandle);
  302.  
  303.         AddResource((Handle)theHHandle, 'TFSS', 255, "\pHeader Info");
  304.  
  305.         err = ResError();
  306.         if (err)
  307.             {
  308.                 ShowError("\pAddResource- TFSS", err);
  309.                 return(err);
  310.             }
  311.  
  312.         /*if we have any sections, write out the records and resources*/
  313.         
  314.         if (theDocument->numSections)
  315.             {
  316.                 /*now write out the section records*/
  317.                 SaveSections(theDocument);
  318.                 
  319.                 /*write the latest versions of all editions to their containers*/
  320.  
  321.                 WriteAllEditions(theDocument);
  322.                 /*now close the resource file*/
  323.                 err = ResError();
  324.                 if (err)
  325.                     {
  326.                         ShowError("\pCloseResFile", err);
  327.                         return(err);
  328.                     }
  329.             }
  330.  
  331.         /*Now put an AppName in for Finder in 7.0*/
  332.  
  333.         theAppName = (StringHandle)NewHandle(6);
  334.         PLstrcpy(*theAppName,"\p7Edit");
  335.         
  336.         AddResource((Handle)theAppName, 'STR ', - 16396, "\pFinder App Info");
  337.  
  338.         err = ResError();
  339.  
  340.         if (err)
  341.             {
  342.                 ShowError("\pAppName", err);
  343.                 return(err);
  344.             }
  345.  
  346.         CloseResFile(resFile);
  347.  
  348.         return(noErr);
  349.     } /* WriteFile */
  350.  
  351. #pragma segment File
  352.  
  353. pascal OSErr ReadFile(DPtr   theDocument,
  354.                                             short  refNum,
  355.                       Str255 fn)
  356.  {
  357.         long            theSize;
  358.         short           resFile;
  359.         OSErr           err;
  360.         HHandle         aHandle;
  361.         Handle          gHandle;
  362.  
  363.         err = GetEOF(refNum, &theSize);
  364.                 if (err)
  365.           return(err);
  366.  
  367.         /*we're only using TE, so check that there is not more than 32K worth of text*/
  368.                 
  369.         if (theSize > 32000)
  370.           return(1);
  371.  
  372.         gHandle = NewHandle(theSize);
  373.         HLock(gHandle);
  374.                 err = FSRead(refNum, &theSize, *gHandle);
  375.                 
  376.         if (err)
  377.           {
  378.             HUnlock(gHandle);
  379.                         return(err);
  380.           }
  381.                                 
  382.                 resFile = HOpenResFile(theDocument->theFSSpec.vRefNum, 
  383.                                                              theDocument->theFSSpec.parID,
  384.                                                              fn,
  385.                                                              fsWrPerm);
  386.                 if (resFile == -1)
  387.                     err = fnfErr;
  388.                     
  389.                 theDocument->numSections = 0;
  390.                 
  391.                 if (err==noErr)
  392.                     {
  393.                         aHandle = nil;
  394.         
  395.                         if (Count1Resources('TFSS'))
  396.                             aHandle = (HHandle)Get1Resource('TFSS', 255);
  397.         
  398.                         if (aHandle)
  399.                             theDocument->numSections = (*aHandle)->numSections;
  400.                             
  401.                         /*
  402.                             New Format Info
  403.                         */
  404.                         
  405.                         aHandle = nil;
  406.                         
  407.                         if (Count1Resources('TFSF'))
  408.                             aHandle = (HHandle)Get1Resource('TFSF', 255);
  409.                             
  410.                         HLock(gHandle);
  411.                         TEStylInsert(    *gHandle,
  412.                                                     GetHandleSize(gHandle),
  413.                                                     (StScrpHandle)aHandle,
  414.                                                     theDocument->theText);
  415.                                         
  416.                         HUnlock(gHandle);
  417.                         
  418.                         /*
  419.                             If there is a print record saved, ditch the old one
  420.                             created by new document and fill this one in
  421.                         */
  422.                         if (Count1Resources('TFSP'))
  423.                             {
  424.                                 if (theDocument->thePrintSetup)
  425.                                     DisposHandle((Handle)theDocument->thePrintSetup);
  426.                                 
  427.                                 theDocument->thePrintSetup = (THPrint)Get1Resource('TFSP', 255);
  428.                               err = HandToHand((Handle *)&theDocument->thePrintSetup);
  429.                                 
  430.                                 PrValidate(theDocument->thePrintSetup);
  431.                             }
  432.                                                     
  433.                         if (theDocument->numSections)
  434.                             {
  435.                                 ReadSectionRecords(theDocument);
  436.                                 ReadAllSectionResources(theDocument);
  437.                             }
  438.         
  439.                         CloseResFile(resFile);
  440.         
  441.                         err = ResError();
  442.                         if (err)
  443.                             {
  444.                                 ShowError("\pread file- CloseResFile", err);
  445.                                 return(err);
  446.                             }
  447.           }
  448.                 else
  449.                     TESetText(*gHandle, 
  450.                               GetHandleSize(gHandle), 
  451.                                         theDocument->theText);
  452.                     
  453.                 if (gHandle)
  454.                     DisposHandle(gHandle);
  455.                     
  456.                 if (err==fnfErr)
  457.                     err = noErr;
  458.  
  459.         return(err);
  460.         } /* ReadFile */
  461.  
  462. /** -----------------------------------------------------------------------
  463.         Name:             GetFileContents
  464.         Purpose:        Opens the document specified by theFSSpec and puts
  465.                                 the contents into theDocument.
  466.      -----------------------------------------------------------------------**/
  467.  
  468.     
  469. #pragma segment File
  470.  
  471. pascal OSErr GetFileContents(FSSpec theFSSpec, DPtr theDocument)
  472.   {
  473.      OSErr            err;
  474.      short            theRefNum;
  475.  
  476.             /*this can be called from two places- on an OpenDoc AppleEvent*/
  477.             /*and by the user just selecting Open from the File Menu*/
  478.             /*assume that the CFS is correct when the routine is called*/
  479.  
  480.             err = FSpOpenDF(&theFSSpec,
  481.                                           fsRdWrPerm,
  482.                                           &theRefNum);
  483.             if (err)
  484.                 {
  485.                     ShowError("\pFSpOpenDF", err);
  486.                     return(err);
  487.                 }
  488.             else
  489.                 {
  490.                     err = ReadFile(theDocument, theRefNum, theFSSpec.name);
  491.                     if (err)
  492.                         {
  493.                             ShowError("\pReadFile", err);
  494.                             return(err);
  495.                         }
  496.                     err=FSClose(theRefNum);
  497.                     if (err)
  498.                         {
  499.                             ShowError("\pFSClose", err);
  500.                             return(err);
  501.                         }
  502.                     return(noErr);
  503.                 }
  504.         }
  505.  
  506.     
  507. #pragma segment File
  508.  
  509. pascal OSErr SaveUsingTemp(DPtr theDocument)
  510.   {
  511.     Str255           tempName;
  512.     OSErr            err;
  513.         FSSpec                tempFSSpec;
  514.  
  515.         /*save the file to disk using a temporary file*/
  516.         /*this is the recommended way of doing things*/
  517.         /*first write out the file to disk using a temporary filename*/
  518.         /*if it is sucessfully written, exchange the temporary file with the last one saved*/
  519.     /*then delete the temporary file- so if anything goes wrong, the original version is still there*/
  520.         /*first generate the temporary filename*/
  521.  
  522.         GetTempFileName(theDocument, &tempName);
  523.         /*create this file on disk*/
  524.  
  525.         tempFSSpec      = theDocument->theFSSpec;
  526.         PLstrcpy(tempFSSpec.name,tempName);
  527.             
  528.         err = DoCreate(tempFSSpec);    
  529.  
  530.         /*now save the file as normal*/
  531.         
  532.         if (err==noErr)
  533.             err = DoSave(theDocument, tempFSSpec);
  534.         
  535.         if (err == noErr)
  536.             err = FSpExchangeFiles(&tempFSSpec, &theDocument->theFSSpec);
  537.  
  538.         /*we've exchanged the files, now delete the temporary one*/
  539.         
  540.         if (err==noErr)
  541.           err = FSpDelete(&tempFSSpec);
  542.  
  543.         return(err);
  544.     }
  545.  
  546.     
  547. #pragma segment File
  548.  
  549. /*
  550.     Fills in the document record with the user chosen destination
  551. */
  552.  
  553. pascal OSErr GetFileNameToSaveAs(DPtr theDocument)
  554.     {            
  555.     StandardFileReply   reply;
  556.     OSErr               err;
  557.         Str255              suggestName;
  558.  
  559.         GetWTitle(theDocument->theWindow, suggestName);
  560.  
  561.         StandardPutFile("\pSave Document As:", suggestName, &reply);
  562.  
  563.     if (reply.sfGood)
  564.             {                
  565.                 err = FSpDelete(&reply.sfFile);
  566.                 
  567.                 if (!((err==noErr) || (err==fnfErr)))
  568.                     return(err);
  569.                 else
  570.                     err = noErr;
  571.                     
  572.                 theDocument->theFSSpec = reply.sfFile;
  573.                 PLstrcpy(theDocument->theFileName, reply.sfFile.name);
  574.             }
  575.         else
  576.             err = userCanceledErr;
  577.         
  578.         return(err);
  579.  } /* GetFileNameToSaveAs */
  580.  
  581.     
  582. #pragma segment File
  583.  
  584. pascal OSErr DoSave(DPtr   theDocument, FSSpec theFSSpec)
  585.   {
  586.     short      refNum;
  587.     OSErr      fileErr;
  588.  
  589.         fileErr = FSpOpenDF(&theFSSpec, fsRdWrPerm, &refNum);
  590.         
  591.         if (fileErr == fnfErr)
  592.             {
  593.               fileErr = DoCreate(theFSSpec);
  594.                 
  595.                 if (fileErr)
  596.                     return(fileErr);
  597.                     
  598.                 fileErr = FSpOpenDF(&theFSSpec, fsRdWrPerm, &refNum);
  599.             }
  600.  
  601.         if (fileErr == noErr)
  602.             {
  603.               fileErr = WriteFile(theDocument, refNum, theFSSpec);
  604.                 
  605.                 if (fileErr==noErr)
  606.                     theDocument->dirty = false;
  607.                     
  608.                 fileErr = FSClose(refNum);
  609.             }
  610.         else
  611.             FileError("\perror opening file ", theFSSpec.name);
  612.         
  613.         return(fileErr);
  614.     }
  615.  
  616.     
  617. #pragma segment File
  618.  
  619. pascal OSErr OpenOld(FSSpec aFSSpec)
  620.     {        
  621.       DPtr  theDocument;
  622.         OSErr fileErr;
  623.  
  624.         theDocument = NewDocument(true);
  625.         
  626.         SetWTitle(theDocument->theWindow, aFSSpec.name);
  627.         
  628.         SetPort(theDocument->theWindow);
  629.         
  630.         theDocument->theFSSpec   = aFSSpec;
  631.         
  632.         PLstrcpy(theDocument->theFileName,aFSSpec.name);
  633.         
  634.         theDocument->dirty       = false;
  635.         theDocument->everSaved   = true;
  636.  
  637.     fileErr = GetFileContents(aFSSpec, theDocument);
  638.         
  639.         if (fileErr == noErr)
  640.             {
  641.                 ResizeWindow(theDocument);
  642.                 ShowWindow(theDocument->theWindow);
  643.             }
  644.         else
  645.             FileError("\pError Opening ", aFSSpec.name);
  646.                     
  647.         return(fileErr);
  648.     } /* OpenOld */
  649.  
  650.     
  651. #pragma segment File
  652.  
  653. pascal OSErr OpenUsingAlias(AliasHandle theAliasH)
  654.   {
  655.     OSErr    err;
  656.     FSSpec   aFSSpec;
  657.     Boolean  dummy;
  658.  
  659.         err = ResolveAlias(nil, theAliasH, &aFSSpec, &dummy);
  660.         
  661.         if (err == noErr)
  662.             err = OpenOld(aFSSpec);
  663.                     
  664.         return(err);
  665.     }
  666.  
  667.